import API from "@/https/api";
import { Message, MessageBox } from "element-ui";
import { getResorceList } from "./auth.js";

/**
 * Created by PanJiaChen on 16/11/18.
 */

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string | null}
 */
export function parseTime(time, cFormat) {
  if (arguments.length === 0) {
    return null;
  }
  const format = cFormat || "{y}-{m}-{d} {h}:{i}:{s}";
  let date;
  if (typeof time === "object") {
    date = time;
  } else {
    if (typeof time === "string" && /^[0-9]+$/.test(time)) {
      time = parseInt(time);
    }
    if (typeof time === "number" && time.toString().length === 10) {
      time = time * 1000;
    }
    date = new Date(time);
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  };
  const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
    const value = formatObj[key];
    // Note: getDay() returns 0 on Sunday
    if (key === "a") {
      return ["日", "一", "二", "三", "四", "五", "六"][value];
    }
    return value.toString().padStart(2, "0");
  });
  return time_str;
}

/**
 * @param {number} time
 * @param {string} option
 * @returns {string}
 */
export function formatTime(time, option) {
  if (("" + time).length === 10) {
    time = parseInt(time) * 1000;
  } else {
    time = +time;
  }
  const d = new Date(time);
  const now = Date.now();

  const diff = (now - d) / 1000;

  if (diff < 30) {
    return "刚刚";
  } else if (diff < 3600) {
    // less 1 hour
    return Math.ceil(diff / 60) + "分钟前";
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + "小时前";
  } else if (diff < 3600 * 24 * 2) {
    return "1天前";
  }
  if (option) {
    return parseTime(time, option);
  } else {
    return (
      d.getMonth() +
      1 +
      "月" +
      d.getDate() +
      "日" +
      d.getHours() +
      "时" +
      d.getMinutes() +
      "分"
    );
  }
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function getQueryObject(url) {
  url = url == null ? window.location.href : url;
  const search = url.substring(url.lastIndexOf("?") + 1);
  const obj = {};
  const reg = /([^?&=]+)=([^?&=]*)/g;
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1);
    let val = decodeURIComponent($2);
    val = String(val);
    obj[name] = val;
    return rs;
  });
  return obj;
}

/**
 * @param {string} input value
 * @returns {number} output value
 */
export function byteLength(str) {
  // returns the byte length of an utf8 string
  let s = str.length;
  for (var i = str.length - 1; i >= 0; i--) {
    const code = str.charCodeAt(i);
    if (code > 0x7f && code <= 0x7ff) s++;
    else if (code > 0x7ff && code <= 0xffff) s += 2;
    if (code >= 0xdc00 && code <= 0xdfff) i--;
  }
  return s;
}

/**
 * @param {Array} actual
 * @returns {Array}
 */
export function cleanArray(actual) {
  const newArray = [];
  for (let i = 0; i < actual.length; i++) {
    if (actual[i]) {
      newArray.push(actual[i]);
    }
  }
  return newArray;
}

/**
 * @param {Object} json
 * @returns {Array}
 */
export function param(json) {
  if (!json) return "";
  return cleanArray(
    Object.keys(json).map(key => {
      if (json[key] === undefined) return "";
      return encodeURIComponent(key) + "=" + encodeURIComponent(json[key]);
    })
  ).join("&");
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function param2Obj(url) {
  const search = url.split("?")[1];
  if (!search) {
    return {};
  }
  return JSON.parse(
    '{"' +
      decodeURIComponent(search)
        .replace(/"/g, '\\"')
        .replace(/&/g, '","')
        .replace(/=/g, '":"')
        .replace(/\+/g, " ") +
      '"}'
  );
}

/**
 * @param {string} val
 * @returns {string}
 */
export function html2Text(val) {
  const div = document.createElement("div");
  div.innerHTML = val;
  return div.textContent || div.innerText;
}

/**
 * Merges two objects, giving the last one precedence
 * @param {Object} target
 * @param {(Object|Array)} source
 * @returns {Object}
 */
export function objectMerge(target, source) {
  if (typeof target !== "object") {
    target = {};
  }
  if (Array.isArray(source)) {
    return source.slice();
  }
  Object.keys(source).forEach(property => {
    const sourceProperty = source[property];
    if (typeof sourceProperty === "object") {
      target[property] = objectMerge(target[property], sourceProperty);
    } else {
      target[property] = sourceProperty;
    }
  });
  return target;
}

/**
 * @param {HTMLElement} element
 * @param {string} className
 */
export function toggleClass(element, className) {
  if (!element || !className) {
    return;
  }
  let classString = element.className;
  const nameIndex = classString.indexOf(className);
  if (nameIndex === -1) {
    classString += "" + className;
  } else {
    classString =
      classString.substr(0, nameIndex) +
      classString.substr(nameIndex + className.length);
  }
  element.className = classString;
}

/**
 * @param {string} type
 * @returns {Date}
 */
export function getTime(type) {
  if (type === "start") {
    return new Date().getTime() - 3600 * 1000 * 24 * 90;
  } else {
    return new Date(new Date().toDateString());
  }
}

/**
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export function debounce(func, wait, immediate) {
  let timeout, args, context, timestamp, result;

  const later = function() {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp;

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last);
    } else {
      timeout = null;
      // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args);
        if (!timeout) context = args = null;
      }
    }
  };

  return function(...args) {
    context = this;
    timestamp = +new Date();
    const callNow = immediate && !timeout;
    // 如果延时不存在，重新设定延时
    if (!timeout) timeout = setTimeout(later, wait);
    if (callNow) {
      result = func.apply(context, args);
      context = args = null;
    }

    return result;
  };
}

/**
 * This is just a simple version of deep copy
 * Has a lot of edge cases bug
 * If you want to use a perfect deep copy, use lodash's _.cloneDeep
 * @param {Object} source
 * @returns {Object}
 */
export function deepClone(source) {
  if (!source && typeof source !== "object") {
    throw new Error("error arguments", "deepClone");
  }
  const targetObj = source.constructor === Array ? [] : {};
  Object.keys(source).forEach(keys => {
    if (source[keys] && typeof source[keys] === "object") {
      targetObj[keys] = deepClone(source[keys]);
    } else {
      targetObj[keys] = source[keys];
    }
  });
  return targetObj;
}

/**
 * @param {Array} arr
 * @returns {Array}
 */
export function uniqueArr(arr) {
  return Array.from(new Set(arr));
}

/**
 * @returns {string}
 */
export function createUniqueString() {
  const timestamp = +new Date() + "";
  const randomNum = parseInt((1 + Math.random()) * 65536) + "";
  return (+(randomNum + timestamp)).toString(32);
}

/**
 * Check if an element has a class
 * @param {HTMLElement} elm
 * @param {string} cls
 * @returns {boolean}
 */
export function hasClass(ele, cls) {
  return !!ele.className.match(new RegExp("(\\s|^)" + cls + "(\\s|$)"));
}

/**
 * Add class to element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function addClass(ele, cls) {
  if (!hasClass(ele, cls)) ele.className += " " + cls;
}

/**
 * Remove class from element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function removeClass(ele, cls) {
  if (hasClass(ele, cls)) {
    const reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
    ele.className = ele.className.replace(reg, " ");
  }
}

var lastUuid = 0;

export function uuid() {
  return new Date().getTime() * 1000 + (lastUuid++ % 1000);
}
export function timeData(date) {
  let dataaStr = new Date(date);
  let month = dataaStr.getMonth() + 1;
  let day = dataaStr.getDate();
  if (month < 10) {
    month = "0" + month;
  }
  if (day < 10) {
    day = "0" + day;
  }
  return dataaStr.getFullYear() + "-" + month + "-" + day;
}

//生成随机字符串
//len 长度 type： num str all
export function makeRandom(len, type) {
  var text = "";
  var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  var possible;
  if (type == "num") {
    possible = "0123456789";
  } else if (type == "str" || !type) {
    possible = str;
  } else if (type == "all") {
    possible = str + "0123456789";
  }
  for (var i = 0; i < len; i++) {
    text += possible.charAt(Math.floor(Math.random() * possible.length));
  }
  return text;
}

export function identification() {
  return new Date().valueOf() + makeRandom(6);
}

/*********自定义函数**********/

//获取字典Value
export function getdictName(dictCode, codeList) {
  let str = "";
  if (Array.isArray(dictCode)) {
    dictCode.map((item, index) => {
      codeList.map(iteminner => {
        if (iteminner.dictCode == item) {
          if (index != dictCode.length - 1) {
            str += iteminner.dictName + "、";
          } else {
            str += iteminner.dictName;
          }
        }
      });
    });
    return str;
  }
  let select = (codeList ? codeList : []).filter(item => {
    return item.dictCode == dictCode;
  });
  return select && select[0] && select[0].dictName ? select[0].dictName : "";
}

export function hasThisButton(code) {
  let resorceList = getResorceList();
  if (resorceList) {
    let selectAttr = resorceList.filter(item => {
      return item == code;
    });
    if (selectAttr && selectAttr.length != 0) {
      return true;
    } else {
      return false;
    }
  }
}

export function ishasValue(row, key) {
  let value = row[key] || row[key] === 0 ? row[key] : "--";
  return value;
}

export function throttle(fn, interval = 500) {
  //节流

  let timer = null;
  let firstTime = true;

  return () => {
    let args = arguments;
    if (firstTime) {
      // 第一次加载
      fn.apply(this, args);
      return (firstTime = false);
    }
    if (timer) {
      // 定时器正在执行中，跳过
      return;
    }

    timer = setTimeout(() => {
      clearTimeout(timer);
      timer = null;
      fn.apply(this, args);
    }, interval);
  };
}

var getWindow = function(node) {
  var doc = node.ownerDocument || node;
  return doc.defaultView || doc.parentWindow;
};

// 获取el位置
export function getClientRect(element) {
  var bcr;
  //trace  IE6下在控制编辑器显隐时可能会报错，catch一下
  try {
    bcr = element.getBoundingClientRect();
  } catch (e) {
    bcr = { left: 0, top: 0, height: 0, width: 0 };
  }
  var rect = {
    left: Math.round(bcr.left),
    top: Math.round(bcr.top),
    height: Math.round(bcr.bottom - bcr.top),
    width: Math.round(bcr.right - bcr.left)
  };
  var doc;
  while (
    (doc = element.ownerDocument) !== document &&
    (element = getWindow(doc).frameElement)
  ) {
    bcr = element.getBoundingClientRect();
    rect.left += bcr.left;
    rect.top += bcr.top;
  }
  rect.bottom = rect.top + rect.height;
  rect.right = rect.left + rect.width;
  return rect;
}

// 下载文件
export function downloadFile(content, filename, type) {
  // 创建隐藏的可下载链接
  let url, blob;
  // 字符内容转变成blob地址
  switch (type) {
    case "excel":
      blob = new Blob([content], {
        type:
          "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"
      });
      url = URL.createObjectURL(blob);
      break;
    case "doc":
      blob = new Blob([content], {
        type:
          "application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=utf-8"
      });
      url = URL.createObjectURL(blob);
      break;
    case "other":
      blob = new Blob([content], {
        type: "application/octet-stream;charset=utf-8"
      });
      url = URL.createObjectURL(blob);
      break;
    case "url":
      url = content;
      break;
    default:
      blob = content;
      url = URL.createObjectURL(blob);
      break;
  }
  let eleLink;
  if (typeof window.navigator.msSaveBlob !== "undefined") {
    // console.log(blob)
    // eleLink = document.createElement("iframe");
    // eleLink.src = url;
    blob
      ? window.navigator.msSaveBlob(blob, filename)
      : window.open(url, "_blank");
  } else {
    eleLink = document.createElement("a");
    eleLink.href = url;
    eleLink.style.display = "none";
    filename ? (eleLink.download = filename) : null;
    document.body.appendChild(eleLink);
    // 触发点击
    eleLink.click();
    // 然后移除
    document.body.removeChild(eleLink);
  }
}

export function judgeLink(to, next) {
  // 路由验证权限
  if (to.meta.authority) {
    let authority = to.meta.authority ? to.meta.authority.split(",") : [],
      judge = true;
    for (let i in authority) {
      if (authority[i] === "unable") {
        judge = true;
        break;
      }
      if (hasThisButton(authority[i])) {
        judge = false;
      }
    }
    if (judge) {
      Message.error("您暂无权限访问该页面");
      next("/reception");
      return false;
    }
  }
  return true;
}

// 获取当前时间/时间戳
export function getTimeNum(j) {
  return j ? new Date() : new Date().valueOf();
}
// 时间戳转换为时间
export function timestampToTime(timestamp) {
  timestamp
    ? (timestamp =
        typeof timestamp == "string"
          ? timeToTimestamp(timestamp)
          : timestamp.valueOf())
    : (timestamp = getTimeNum());
  let date = new Date(timestamp);
  let Y = date.getFullYear();
  let M =
    date.getMonth() + 1 < 10
      ? "0" + (date.getMonth() + 1)
      : date.getMonth() + 1;
  let D = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
  let h = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
  let m = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
  let s = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
  let w = date.getDay();
  return {
    Year: Y,
    Month: M,
    Day: D,
    Hour: h,
    Minite: m,
    Second: s,
    Week: w
  };
}
// 上下午时间
export function transTime(time, en) {
  if (time) {
    let timeArr = time.split(":");
    timeArr[0] =
      Number(timeArr[0]) > 12
        ? en
          ? Number(timeArr[0] - 12) + (en === "small" ? "pm" : "PM")
          : "下午 " + Number(timeArr[0] - 12)
        : en
        ? timeArr[0] + (en === "small" ? "am" : "AM")
        : "上午 " + timeArr[0];
    return timeArr.join(":");
  }
  return time;
}
// 时间格式化
export function TimeTransform(type, addtime, updatetime) {
  if (!addtime && !updatetime) {
    addtime = getTimeNum();
  }
  let time;
  if (updatetime && updatetime != null && updatetime != "") {
    time = updatetime;
  } else {
    time = addtime;
  }
  if (type) {
    let time_trans, NewTime;
    // console.log(NewTime)
    type === "差值" ? null : (NewTime = timestampToTime(time));
    switch (type) {
      case "区间":
        let UntilTime = Math.round(
          parseInt(Number(getTimeNum()) / 1000 - Number(time)) / 3600
        );
        if (UntilTime == 0) {
          let UntilT = parseInt(
            (60 * (Number(getTimeNum()) / 1000 - Number(time))) / 3600
          );
          UntilT = UntilT == 0 ? 1 : UntilT;
          time_trans = UntilT + "分钟前";
        } else if (UntilTime < 24) {
          time_trans = UntilTime + "小时前";
        } else if (UntilTime < 48) {
          time_trans = "1天前";
        } else if (UntilTime < 72) {
          time_trans = "2天前";
        } else {
          time_trans =
            NewTime.Year +
            "年" +
            NewTime.Month +
            "月" +
            NewTime.Day +
            "日 " +
            NewTime.Hour +
            ":" +
            NewTime.Minite;
        }
        break;
      case "差值":
        if (!addtime || !updatetime) {
          return "";
        }
        let j = false;
        addtime =
          typeof addtime == "string"
            ? timeToTimestamp(addtime)
            : addtime.valueOf();
        updatetime =
          typeof updatetime == "string"
            ? timeToTimestamp(updatetime)
            : updatetime.valueOf();
        time = (updatetime - addtime) / 1000;
        time < 0 ? ((time = -time), (j = true)) : null;
        let d = 24 * 60 * 60,
          h = 60 * 60,
          m = 60;
        let day = Math.floor(time / d),
          hour = Math.floor((time % d) / h),
          minite = Math.floor(((time % d) % h) / m),
          second = Math.floor(((time % d) % h) % m);
        // console.log(day,hour,minite,second)
        time_trans = { day, hour, minite, second };
        // time_trans=day?
        // (day+'天'+(hour?(hour+'小时'):'1小时')):
        // ((hour?(hour<10?('0'+hour):hour):'00')+':'+(minite?(minite<10?('0'+minite):minite):'00')+':'+(second?(second<10?('0'+second):second):'01'));
        time_trans =
          (day ? day + "天" : "") +
          ((hour ? hour + "小时" : "") + (minite ? minite + "分" : ""));
        j ? (time_trans = "-" + time_trans) : null;
        break;
      default:
        type = type.replace("YYYY", NewTime.Year);
        type = type.replace("YY", NewTime.Year.toString().slice(2, 4));
        type = type.replace("MM", NewTime.Month);
        type = type.replace("M", Number(NewTime.Month));
        type = type.replace("DD", NewTime.Day);
        type = type.replace("D", Number(NewTime.Day));
        type = type.replace("hh", NewTime.Hour);
        type = type.replace("mm", NewTime.Minite);
        type = type.replace("ss", NewTime.Second);
        let week = ["日", "一", "二", "三", "四", "五", "六"];
        let weekTxt =
          NewTime.Week || NewTime.Week === 0 ? week[Number(NewTime.Week)] : "";
        type = type.replace("W", weekTxt);
        return type;
    }
    return time_trans;
  }
  return addtime;
}
// 时间转换为时间戳
export function timeToTimestamp(value) {
  var time = null;
  if (value !== "" && value !== null) {
    value = value.toString();
    value = value.split("/").join(",");
    value = value.split(" ").join(",");
    value = value.split("-").join(",");
    value = value.split(":").join(",");
    var arr = value.split(",");
    for (var i = 0; i < arr.length; i++) {
      if (arr[i] == null) {
        arr.splice(i, 1);
        i--;
      }
    }
    time = new Date(
      arr[0],
      arr[1] - 1,
      arr[2],
      arr[3] ? arr[3] : 0,
      arr[4] ? arr[4] : 0,
      arr[5] ? arr[5] : 0
    );
    time = time.valueOf();
  }
  return time;
}
// 本年第几周
export function getWeekOfYear(today) {
  var today = today ? new Date(timeToTimestamp(today)) : new Date();
  var firstDay = new Date(today.getFullYear(), 0, 1);
  var dayOfWeek = firstDay.getDay();
  var spendDay = 1;
  if (dayOfWeek != 0) {
    spendDay = 7 - dayOfWeek + 1;
  }
  firstDay = new Date(today.getFullYear(), 0, 1 + spendDay);
  var d = Math.ceil((today.valueOf() - firstDay.valueOf()) / 86400000);
  var result = Math.ceil(d / 7);
  return result + 1;
}
// 获取本月天数
export function getDays(n) {
  var today = new Date();
  var d = new Date(
    today.getFullYear(),
    Number(today.getMonth() + 1 + (n ? n : 0)),
    0
  );
  return d.getDate();
}
// 自定义element提示框确认框样式
export function alertFn(msg, type) {
  Message({
    iconClass: type ? "el-icon-circle-check" : "el-icon-circle-close",
    customClass: `troila-alert troila-alert-${type ? "success" : "error"}`,
    message: msg ? msg : type ? "成功" : "失败",
    type: type ? "success" : "error",
    showClose: type ? false : true,
    duration: 3000
  });
}

export function confirmFn(text, title, config) {
  MessageBox.confirm(text, title, {
    type: "warning",
    customClass: "troila-confirm",
    dangerouslyUseHTMLString: true,
    ...config
  });
}
// 递归获取数据
export function recursion(
  item_,
  id = "id",
  children = "children",
  disabled = "disabled"
) {
  let item = JSON.parse(JSON.stringify(item_));
  let arr = [];
  item && item[disabled] ? null : arr.push(item[id]);
  if (item[children] && item[children].length > 0) {
    for (let i in item[children]) {
      arr = arr.concat(recursion(item[children][i], id, children));
    }
  }
  return arr;
}
// 递归成树
export function toTree(
  arr,
  code = null,
  id = "id",
  children = "children",
  pid = "pid"
) {
  if (arr.length == 0) {
    return [];
  }
  let allTree = arr.filter(v =>
    !code
      ? v[pid] === undefined ||
        v[pid] === "" ||
        v[pid] === null ||
        v[pid] === 0 ||
        v[pid] === "0"
      : v[pid] == code
  );
  return allTree.map(v => {
    v.children = toTree(
      arr.filter(
        v =>
          !(!code
            ? v[pid] === undefined ||
              v[pid] === "" ||
              v[pid] === null ||
              v[pid] === 0 ||
              v[pid] === "0"
            : v[pid] == code)
      ),
      v[id]
    );
    v[children].length == 0 ? delete v[children] : null;
    return {
      ...v
    };
  });
}
export function JudgeClass(el, name) {
  var e = el || window.event || arguments[0];
  var elme = e.target || e.srcElement;
  var className = [];
  var getclass = function() {
    if (elme.classList && elme.classList.length > 0) {
      className.push(elme.classList);
    }
    if (elme.parentElement || elme.parentNode) {
      elme = elme.parentElement || elme.parentNode;
      getclass();
    }
  };
  getclass();
  if (name) {
    let names = name.split(",");
    for (var i = 0; i < className.length; i++) {
      for (var j = 0; j < className[i].length; j++) {
        if (names.indexOf(className[i][j]) > -1) {
          return true;
        }
      }
    }
  }
  return false;
}

export function getMatched(this_) {
  // console.log(this_.$route)
  if (!this_.$route.meta || !this_.$route.meta.title) {
    return [];
  }
  // console.log(this_.$route.matched)
  let matched = this_.$route.matched.filter(
    item =>
      this_.$route.meta &&
      this_.$route.meta.title &&
      (item.name === this_.$route.name ||
        (this_.$route.meta.pname && item.name === this_.$route.meta.pname))
  );
  // console.log(matched)
  if (matched.length == 0) {
    return [];
  }
  const first = matched[0];
  if (first.name === this_.$route.name) {
    matched = [first];
  }
  return matched.map(v => v.meta.title);
}

export function getItemVal(arr, key, id, opt = {}) {
  let idname = opt.idname || "id",
    children = opt.children || "children";
  for (let i in arr) {
    if (arr[i][idname] == id) {
      console.log(arr[i][key], key, arr[i], id);
      return arr[i][key];
    }
    if (arr[i][children] && arr[i][children].length > 0) {
      let res = getItemVal(arr[i][children], key, id, opt);
      if (res !== null) {
        return res;
      }
    }
  }
  return null;
}
